package org.expath.pkg.saxon.java;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import javax.xml.transform.stream.StreamSource;
import net.sf.saxon.query.ModuleURIResolver;
import net.sf.saxon.trans.XPathException;
import org.apache.xml.resolver.CatalogManager;

/**
 * ...
 *
 * @author Florent Georges
 * @date   2009-10-29
 */
public class PkgModuleResolver
        implements ModuleURIResolver
{
    /** Constructor */
    public PkgModuleResolver(CatalogManager manager)
    {
        myManager = manager;
    }

    // Inspired from Norm's org.apache.xml.resolver.tools.CatalogResolver#resolve(String,String)...
    //
    public StreamSource[] resolve(String module_uri, String base_uri, String[] locations)
            throws XPathException
    {
        // can arise for instance when compiling XQuery from a file and using
        // the option -u (treat everything as a URI, so here, we only have a
        // location, and it is tried to be resolved...)
        if ( module_uri == null ) {
            return null;
        }

        String result = null;
        try {
            result = myManager.getCatalog().resolveURI(module_uri);
        }
        catch ( Exception ex ) {
            // nop;
        }

        // do not use Base URI, the module URI must be absolute!
        if ( result == null ) {
            try {
                result = new URL(module_uri).toString();
            }
            catch ( MalformedURLException ex ) {
                throw new XPathException("Malformed absolute URL " + module_uri + "(base " + base_uri + ")", ex);
            }
        }

        myManager.debug.message(2, "Resolved URI", module_uri, result);

        if ( result.startsWith("file:") ) {
            result = "file:///" + result.substring(5);
        }
        else {
            return null;
        }
        File f;
        InputStream in;
        try {
            f = new File(new URI(result));
            in = new FileInputStream(f);
        }
        catch ( FileNotFoundException ex ) {
            throw new XPathException("Error opening file", ex);
        }
        catch ( URISyntaxException ex ) {
            throw new XPathException("Error parsing URI", ex);
        }
        StreamSource[] source = new StreamSource[1];
        source[0] = new StreamSource(in);
        source[0].setSystemId(f);
        return source;
    }

    /** The catalog manager (the parent 's one is not visible)*/
    private CatalogManager myManager;
}
